package com.myaihui.controller;

import com.myaihui.config.FileConfig;
import com.myaihui.domain.Attachment;
import com.myaihui.foundation.model.Pager;
import com.myaihui.foundation.domain.ueditor.PageResult;
import com.myaihui.foundation.domain.ueditor.UploadResult;
import com.myaihui.foundation.query.FileQuery;
import com.myaihui.service.FileService;
import com.myaihui.util.LoginUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.util.*;

/**
 * Created by sun on 2018/6/5.
 *
 * @author sunfuchang03@126.com
 * @version 1.0
 * @since 1.0
 */
@Controller
@RequestMapping("/ueditor")
public class UEditorController {
    /*
     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     *
     * Static fields/constants/initializer
     *
     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     */

    private static Logger log = LoggerFactory.getLogger(UEditorController.class);

    public static final String UEDITOR_BACKEND_CONFIG = getConfigJson();

    public static final String IMAGE_FOLDER_NAME = "image";
    public static final String FILE_FOLDER_NAME = "file";

    /*
     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     *
     * Instance fields
     *
     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     */

    @Autowired
    private FileService fileService;
    @Autowired
    private FileConfig fileConfig;

    /*
     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     *
     * Constructors
     *
     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     */



    /*
     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     *
     * Public Methods
     *
     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     */

    @RequestMapping("/config")
    @ResponseBody
    public String request() {
        return UEDITOR_BACKEND_CONFIG;
    }

    @RequestMapping(value = "/uploadImage", method = RequestMethod.POST)
    @ResponseBody
    public UploadResult uploadImage(@RequestParam("images") MultipartFile file) {
        if (file != null) {
            String fileSaveDir = "/" + IMAGE_FOLDER_NAME;
            return upload(fileSaveDir, Attachment.BusinessType.CONTENT_IMAGE, file);
        }
        return new UploadResult();
    }

    @RequestMapping(value = "/uploadFile", method = RequestMethod.POST)
    @ResponseBody
    public UploadResult uploadFile(@RequestParam("files") MultipartFile file) {
        UploadResult result = new UploadResult();
        if (file != null) {
            String fileSaveDir = "/" + FILE_FOLDER_NAME;
            return upload(fileSaveDir, Attachment.BusinessType.CONTENT_ATTACHMENT, file);
        }
        return new UploadResult();
    }

    @RequestMapping(value = "/listImage")
    @ResponseBody
    public PageResult listImage(int start, int size) {
        if (start < 0) {
            start = 0;
        }
        if (size <= 0) {
            size = 20;
        }

        PageResult pageResult = new PageResult();

        FileQuery query = new FileQuery();
        query.setiDisplayStart(start);
        query.setiDisplayLength(size);
        query.setIncludeFileType(new Integer[]{Attachment.FileType.IMAGE});
        query.setUserId(LoginUtil.loginUser().getId());
        Pager<Attachment> attachmentPager = fileService.pageQuery(query);
        List<Attachment> attachments = attachmentPager.getAaData();

        if (attachments != null) {
            pageResult.setState("SUCCESS");
            pageResult.setStart(start);
            pageResult.setTotal(attachments.size());
        }

        List<Map<String, Object>> urls = new ArrayList<>();
        pageResult.setList(urls);
        for (Attachment attachment : attachmentPager.getAaData()) {
            Map<String, Object> map = new HashMap<>();
            map.put("url", fileConfig.getUrl() + attachment.getPath());
            urls.add(map);
        }
        return pageResult;
    }

    @RequestMapping(value = "/listFile")
    @ResponseBody
    public PageResult listFile(int start, int size) {
        if (start < 0) {
            start = 0;
        }
        if (size <= 0) {
            size = 20;
        }

        PageResult pageResult = new PageResult();

        FileQuery query = new FileQuery();
        query.setiDisplayStart(start);
        query.setiDisplayLength(size);
        query.setExcludeFileType(new Integer[]{Attachment.FileType.IMAGE});
        query.setUserId(LoginUtil.loginUser().getId());
        Pager<Attachment> attachmentPager = fileService.pageQuery(query);
        List<Attachment> attachments = attachmentPager.getAaData();

        if (attachments != null) {
            pageResult.setState("SUCCESS");
            pageResult.setStart(start);
            pageResult.setTotal(attachments.size());
        }

        List<Map<String, Object>> urls = new ArrayList<>();
        pageResult.setList(urls);
        for (Attachment attachment : attachmentPager.getAaData()) {
            Map<String, Object> map = new HashMap<>();
            map.put("url", fileConfig.getUrl() + attachment.getPath());
            urls.add(map);
        }
        return pageResult;
    }

    /*
     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     *
     * Private Methods
     *
     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     */

    private static String getConfigJson() {
        InputStream is = UEditorController.class.getResourceAsStream("/ueditor-config.json");
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));

        char[] buff = new char[1024];
        StringBuilder sb = new StringBuilder();
        try {
            while ((reader.read(buff, 0, 1024)) != -1) {
                sb.append(buff);
                buff = new char[1024];
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return sb.toString().trim();
    }

    private UploadResult upload(String fileSaveDir, Integer businessType, MultipartFile file) {
        UploadResult result = new UploadResult();
        try {
            List<Attachment> attachments = fileService.upload(fileSaveDir, businessType, LoginUtil.loginUser().getId(), file);
            if (attachments != null && attachments.size() > 0) {
                Attachment attachment = attachments.get(0);
                result.setState("SUCCESS");
                result.setUrl(fileConfig.getUrl() + attachment.getPath());
                result.setName(attachment.getSaveName());
                result.setOriginal(attachment.getOriginalName());
                result.setSize(attachment.getSize());
            }
        } catch (IOException e) {
            log.error("Upload exception : ", e);
        }
        return result;
    }
}